<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="../react18/react.development.js"></script>
    <script src="../react18/react-dom.development.js"></script>
    <script src="../react18/babel.min.js"></script>
  </head>
  <body>
    <button id="btn">按钮</button>
    <div id="app"></div>
    <script type="text/babel">
      const oBtn = document.getElementById("btn");

      //得到一个初始的列表数据
      const userData = ["HTML", "CSS", "JavaScript", "NodeJS"];

      /* 
        diff算法的key属性:
          * 同层级中相同的节点，但由于位置顺序发生变化，导致需要进行繁杂低效的删除、创建操作(默认是按照顺序依次比较的)，其实只要对这些节点进行位置移动即可。那么就需要引入key机制
          * 当某个节点添加了同级节点中唯一的key属性，当它在当前层级的位置发生了变化后,react diff算法通过新旧节点比较后(如果节点上有key属性,则会去寻找对应的key)，如果发现了key值相同的新旧节点，就会执行移动操作（然后依然按原策略深入节点内部的差异对比更新），而不会执行原策略的删除旧节点，创建新节点的操作。
          * React官方建议不要用遍历的index作为这种场景下的节点的key属性值,因为每一个元素对应的index的值会随着结构的改变而发生变化
          * key使用的注意点:
            1. key在列表中要唯一性(不是全局唯一性)
            2. key要具有稳定性(当前数据固定对应的唯一值)(注意如果有逆序修改数据,则不要使用index)
      

        如果有逆序的修改,则不建议使用下标做key
          li HTML key=0
          li CSS key=1
          li JavaScript key=2
          li NodeJS key=3

          li React key=0
          li HTML key=1
          li CSS key=2
          li JavaScript key=3
          li NodeJS key=4

        建议使用当前数据对应的唯一值(如果没有,可以使用当前的item)
          li HTML key=HTML
          li CSS key=CSS
          li JavaScript key=JavaScript
          li NodeJS key=NodeJS

          li React key=React
          li HTML key=HTML
          li CSS key=CSS
          li JavaScript key=JavaScript
          li NodeJS key=NodeJS
      */
      //根据数据 列表渲染
      const vDom = (
        <ul>
          {userData.map((item) => {
            return <li key={item}>{item} <input type="text" /></li>;
          })}
        </ul>
      );

      //渲染
      const root = ReactDOM.createRoot(document.getElementById("app"));
      root.render(vDom);

      //点击按钮改变数据重新渲染
      oBtn.onclick = function () {
        userData.unshift("React");

        //重新得到虚拟DOM,然后渲染
        const vDom = (
          <ul>
            {userData.map((item) => {
              return <li key={item}>{item}
                <input type="text" /></li>;
            })}
          </ul>
        );

        root.render(vDom);
      };
    </script>
  </body>
</html>
